package controllers

import (
	"my-go-project/model"
	"my-go-project/utils/token"
	"net/http"

	"github.com/gin-gonic/gin"
)

func PostPassageLike(c *gin.Context) {
	var p model.PassageLike
	if err := c.ShouldBindBodyWithJSON(&p); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"data": err.Error(),
		})
		return
	}

	userID, _ := token.ExtractTokenID(c)

	p.UserID = int(userID)
	_, err := p.SavePassageLike()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"data": err.Error(),
		})
		return
	}

	receID, _ := model.GetAuthorID(p.PassageID)

	m := model.Message{
		PassageID:  p.PassageID,
		Type:       "passage_like",
		SenderID:   int(userID),
		ReceiverID: receID,
	}

	hadLike, err := m.IsLikeOccured()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}

	if !hadLike && m.SenderID != m.ReceiverID {
		_, err = m.SaveMessage()
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"error": err.Error(),
			})
			return
		}
	}

	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}

	err = model.UpdatePassageLikeNum(1, p.PassageID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "like success",
	})
}

func UndoPassageLike(c *gin.Context) {
	var p model.PassageLike
	if err := c.ShouldBindBodyWithJSON(&p); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": err.Error(),
		})
		return
	}
	userID, _ := token.ExtractTokenID(c)
	p.UserID = int(userID)
	_, err := p.DeletePassageLike()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}

	err = model.UpdatePassageLikeNum(-1, p.PassageID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "delete like success",
	})
}

func PostCommentLike(c *gin.Context) {
	var p model.CommentLike
	if err := c.ShouldBindBodyWithJSON(&p); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"data": err.Error(),
		})
		return
	}
	userID, _ := token.ExtractTokenID(c)
	p.UserID = int(userID)
	_, err := p.SaveCommentLike()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"data": err.Error(),
		})
		return
	}

	receID, _ := model.GetCommentUserID(p.CommentID)
	passageID, _ := model.GetPassageIDByCommentID(p.CommentID)

	m := model.Message{
		PassageID:  passageID,
		Type:       "comment_like",
		SenderID:   int(userID),
		ReceiverID: receID,
		CommentID:  p.CommentID,
	}

	hadLike, err := m.IsLikeOccured()
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": err.Error(),
		})
		return
	}

	if !hadLike && m.SenderID != m.ReceiverID {
		_, err = m.SaveMessage()
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"error": err.Error(),
			})
			return
		}
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "like success",
	})
}

func UndoCommentLike(c *gin.Context) {
	var p model.CommentLike
	if err := c.ShouldBindBodyWithJSON(&p); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"data": err.Error(),
		})
		return
	}
	userID, _ := token.ExtractTokenID(c)
	p.UserID = int(userID)
	_, err := p.DeleteCommentLike()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"data": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"message": "delete like success",
	})
}
